#ifndef SPECIALTERM_CLASS
#define SPECIALTERM_CLASS


class SpecialTerm {
	friend class FeatureTerm;
	friend class FeatureTermContainer;

public:
	/*  ------------- BEGIN: These functions have to be redefined for each special object: --------------- */ 
	SpecialTerm(Sort *sort);
	virtual ~SpecialTerm(void);

	static void createSort(Ontology *o);	/* Creates the proper sort in the ontology, so that this specialterm class */ 
											/* can be used as any other feature term.								   */ 
	virtual SpecialTerm *newSpecialTerm(Sort *sort,List<Symbol> *names,List<FeatureTerm> *arguments);	/* Virtual function that calls the appropriate */ 
																										/* constructor to create SpecialTerms		   */ 

	virtual SpecialTerm *clone(void);				/* Makes an independent copy of the Term */ 
	virtual SpecialTerm *clone(class FTKBase *dm);	/* Makes an independent copy of the Term, but does  */ 
													/* not duplicate those elements of the domain model			*/ 

	virtual List<FeatureTerm> *DSpecialization(List<FeatureTerm> *objects,Ontology *ontology,FTKBase *domain_model);
	virtual List<FeatureTerm> *DSpecialization_b(List<FeatureTerm> *objects,Ontology *ontology,FTKBase *domain_model);
	virtual List<FeatureTerm> *DGeneralization(Ontology *ontology,FTKBase *domain_model);
	virtual List<FeatureTerm> *unification(FeatureTerm *f2,Ontology *ontology,FTKBase *domain_model);
	virtual bool subsumes(FeatureTerm *f);

	virtual SpecialTerm *random(void);
	/*  ------------- END: These functions have to be redefined for each special object: --------------- */ 

	Sort *getSort(void);

	FeatureTerm *featureValue(Symbol *feature);
	FeatureTerm *featureValueQuick(Symbol *feature); 
	FeatureTerm *featureValue(char *feature);
	FeatureTerm *featureValueQuick(char *feature); 
	List<FeatureTerm> *readPath(Path *path);

	char *toStringNOOS(void);
	char *toStringNOOS(FTKBase *dm); /* Does not expand the objects present in the domain model but prints their name */ 
	static FeatureTerm *fromStringNOOS(char *s,FTKBase *m,Ontology *o);

	FeatureTerm *clone_substituting(FeatureTerm *v1,FeatureTerm *v2);
	FeatureTerm *clone_substituting(FeatureTerm *v1,FeatureTerm *v2,FTKBase *dm);
	FeatureTerm *clone_linking(FeatureTerm *v1,FeatureTerm *v2,FTKBase *dm);
	FeatureTerm *clone_keepingTrackOfNode(FeatureTerm *node,FeatureTerm **newnode,FTKBase *dm);
	FeatureTerm *clone_keepingTrackOf2Nodes(FeatureTerm *node1,FeatureTerm **newnode1,FeatureTerm *node2,FeatureTerm **newnode2,FTKBase *dm);
	int substitute(FeatureTerm *v1,FeatureTerm *v2);

	bool hasSetsP(void);
	bool hasPathEqualtiesP(void);
	bool hasPathEqualtiesP(class FTKBase *dm); // does not consider equalties of domain objects as path equalties 

	bool leafP(void);	/* True if the object is an integer, float, symbol or a FT without features */ 


protected:
	Sort *m_sort;
	List<Symbol> m_names;			// This is a list containing the set of features avilable to read (defined in the sort)
	List<FeatureTerm> m_values;

private:

};

#endif
